/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package cn.apestar.modules.report.useraccount.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.apestar.common.persistence.Page;
import cn.apestar.common.service.CrudService;
import cn.apestar.modules.report.useraccount.dao.UserAccountDao;
import cn.apestar.modules.report.useraccount.entity.TerminalCount;
import cn.apestar.modules.report.useraccount.entity.UserAccount;
import cn.apestar.modules.report.useraccount.util.UserAccountUtil;

/**
 * 用户账户Service
 * @author yudw
 * @version 2016-08-18
 */
@Service
@Transactional(readOnly = true)
public class UserAccountService extends CrudService<UserAccountDao, UserAccount> {

    public UserAccount get(String id) {
        return super.get(id);
    }

    public List<UserAccount> findList(UserAccount userAccount) {
        return super.findList(userAccount);
    }

    public Page<UserAccount> findPage(Page<UserAccount> page, UserAccount userAccount) {
        return super.findPage(page, userAccount);
    }

    public Long sumDeposit(UserAccount userAccount) {
        return dao.sumDeposit(userAccount);
    }

    @Transactional(readOnly = false)
    public void save(UserAccount userAccount) {
        super.save(userAccount);
    }

    @Transactional(readOnly = false)
    public void delete(UserAccount userAccount) {
        super.delete(userAccount);
    }

    public Page<UserAccount> getCount(Page<UserAccount> page, UserAccount entity) {

        entity.setPage(page);

        List listDate = null;

        Date nowDate = new Date();
        UserAccountUtil.setLocalDate(nowDate);
        UserAccountUtil.setNowDate(nowDate);

        if (setRequestTimeCase(listDate, entity)) {

            /*
             * int dayCount; try { dayCount = UserAccountUtil.daysBetween("2016-10-01", "2016-10-31"); System.out.println(dayCount); } catch
             * (ParseException e) { e.printStackTrace(); }
             */

            List<UserAccount> listOfAll = dao.getAllCount(entity);

            entity.setPage(null);

            List<UserAccount> countList = dao.getCount(entity);

            List<UserAccount> countListAll = new ArrayList<>();

            addEmptyObj(countList, countListAll, entity);
            UserAccountUtil.initDataList(countList, "terminal", "createDate", true);
            UserAccountUtil.colMapBackToList();

            dealWithOfAssembly(countList, countListAll, listOfAll);

            handlerDataWithDate(countList, countListAll);
            page.setList(countListAll);
            return page;
        }
        page.setList(null);
        return page;
    }

    private boolean setRequestTimeCase(List<?> listDate, UserAccount request) {
        Date startDate = request.getStartDate();
        Date endDate = request.getEndDate();
        UserAccountUtil.setRecordCount(10);
        if (UserAccountUtil.compareDate(startDate, endDate) > 0)
            return false;
        Date nowdDate = UserAccountUtil.getNowDate();
        String nowDateS = new SimpleDateFormat("yyyy-MM-dd").format(nowdDate);
        if (startDate != null && endDate != null) {
            String endDateS = new SimpleDateFormat("yyyy-MM-dd").format(endDate);
            if (endDateS.compareTo(nowDateS) > 0) {
                endDate = nowdDate;
                request.setStartDate(endDate);
                UserAccountUtil.setLocalDate(endDate);
            }
            listDate = UserAccountUtil.getOffsetDateList(startDate, endDate);
        } else if (startDate != null) {
            listDate = UserAccountUtil.getAfterXDayListByDate(startDate, 10);
        } else if (endDate != null) {
            String endDateS = new SimpleDateFormat("yyyy-MM-dd").format(endDate);
            if (endDateS.compareTo(nowDateS) > 0) {
                endDate = nowdDate;
                request.setStartDate(endDate);
            }
            UserAccountUtil.setLocalDate(endDate);
            listDate = UserAccountUtil.getBeforeXDayListByDate(10);
        } else {
            listDate = UserAccountUtil.getBeforeXDayListByDate(10);
        }
        int first = 0;
        int last = listDate.size() - 1;
        /*
         * List<?> dealedList = UserAccountUtil .getBeforeXDayListByDate((Date) listDate.get(last), (Date) listDate.get(first),
         * UserAccountUtil.getRecordCount());
         */
        request.setStartDate((Date) listDate.get(last));
        request.setEndDate((Date) listDate.get(first));
        return true;
    }

    private void addEmptyObj(List<UserAccount> listData, List<UserAccount> listDataAll, UserAccount userAccount) {
        List<?> listDateString = UserAccountUtil.getBeforeXDayListByString(userAccount.getStartDate(), userAccount.getEndDate(), "yyyy-MM-dd",
                                                                           UserAccountUtil.getRecordCount());
        List<?> listDateDate = UserAccountUtil.getAfterXDayListByDate(userAccount.getStartDate(), UserAccountUtil.getRecordCount());
        /*
         * Map<String, String> date_index = new HashMap<>(); int index = listDate.size() > listData.size() ? listDate.size() : listData.size(); for
         * (int i = 0; i < index; ++i) { String dateString = new SimpleDateFormat("yyyy-MM-dd").format(date_index.get(i)); }
         */
        List<String> date_index = getListDate(listData, userAccount);
        for (int i = listDateString.size() - 1; i >= 0; --i) {
            Date date = (Date) listDateDate.get(i);
            if (!date_index.contains(listDateString.get(i))) {
                int pos = date_index.indexOf(listDateString.get(i));
                UserAccount emptyUserAccout = new UserAccount();
                emptyUserAccout.setCreateDate(date);
                listData.add(emptyUserAccout);
            }
            UserAccount emptyUserAccout = new UserAccount();
            emptyUserAccout.setCreateDate(date);
            /*
             * emptyUserAccout.setIosCount(listData.get(i).getIosCount()); emptyUserAccout.setAndroidCount(listData.get(i).getAndroidCount());
             * emptyUserAccout.setAllCount(listData.get(i).getAllCount());
             */
            listDataAll.add(emptyUserAccout);
        }
        Collections.sort(listDataAll);
    }

    private List<String> getListDate(List<UserAccount> listData, UserAccount userAccount) {
        List<?> listDate = UserAccountUtil.getBeforeXDayListByString(userAccount.getStartDate(), userAccount.getEndDate(), "yyyy-MM-dd",
                                                                     UserAccountUtil.getRecordCount());
        List<String> resultMap = new ArrayList<>();
        for (int i = 0; i < listData.size(); ++i) {
            UserAccount userAccountFromList = listData.get(i);
            Date createDate = userAccountFromList.getCreateDate();
            String date = new SimpleDateFormat("yyyy-MM-dd").format(createDate);
            if (resultMap.contains(date))
                continue;
            resultMap.add(date);
        }
        return resultMap;
    }

    private void dealWithOfAssembly(List<UserAccount> listOfDay, List<UserAccount> listOfAll, List<UserAccount> countList) {
        int indexOfDay = listOfAll.size() - 1;
        int indexOfAll = listOfDay.size() - 1;
        UserAccount firstUserAccount = listOfAll.get(indexOfDay);
        UserAccount firstUserAccountOfDay = listOfDay.get(indexOfAll);
        UserAccountUtil.initDataList(countList, "createDate", "terminal", true);
        UserAccount iosFromColName = (UserAccount) UserAccountUtil.getObjFromColName("2000-01-01", "ios");
        UserAccount androidFromColName = (UserAccount) UserAccountUtil.getObjFromColName("2000-01-01", "android");
        UserAccount webFromColName = (UserAccount) UserAccountUtil.getObjFromColName("2000-01-01", "web");
        UserAccount otherFromColName = (UserAccount) UserAccountUtil.getObjFromColName("2000-01-01", "other");

        String iosCount = null;
        if (getSafeValueAsObj(iosFromColName))
            iosCount = iosFromColName.getCount();
        String androidCount = null;
        if (getSafeValueAsObj(androidFromColName))
            androidCount = androidFromColName.getCount();
        String webCount = null;
        if (getSafeValueAsObj(webFromColName))
            webCount = webFromColName.getCount();
        String otherCount = null;
        if (getSafeValueAsObj(otherFromColName))
            otherCount = otherFromColName.getCount();

        int iosCountInt = getSafeValueAsInt(iosCount);
        int androidCountInt = getSafeValueAsInt(androidCount);

        /*
         * 网页日期前总量
         */
        int webCountInt = getSafeValueAsInt(webCount);
        /*
         * 其他来源日期前总量
         */
        int otherCountInt = getSafeValueAsInt(otherCount);

        firstUserAccount.setAndroidCount(String.valueOf(androidCountInt));
        firstUserAccount.setIosCount(String.valueOf(iosCountInt));
        firstUserAccount.setOtherCount(String.valueOf(webCountInt + otherCountInt));

        firstUserAccountOfDay.setAndroidCount(String.valueOf(androidCountInt));
        firstUserAccountOfDay.setIosCount(String.valueOf(iosCountInt));
        firstUserAccountOfDay.setOtherCount(String.valueOf(webCountInt + otherCountInt));
    }

    /**
     * 处理注册量
     * @param listOfDay
     * @param listOfAll
     */
    private void handlerDataWithDate(List<UserAccount> listOfDay, List<UserAccount> listOfAll) {
        int index = listOfAll.size() - 1;
        TerminalCount terminalCount = new TerminalCount();
        UserAccountUtil.initDataList(listOfDay, "terminal", "createDate", true);
        UserAccount userAccountInit = listOfAll.get(index);
        String iosCount = userAccountInit.getIosCount();
        String androiCount = userAccountInit.getAndroidCount();
        String otherAnother = userAccountInit.getOtherCount();
        long iosCountIntAnother = getSafeValueAsInt(iosCount);
        long androiCountIntAnother = getSafeValueAsInt(androiCount);
        long otherAnotherIntAnther = getSafeValueAsInt(otherAnother);
        terminalCount.setAndroidCount(androiCountIntAnother);
        terminalCount.setIosCount(iosCountIntAnother);
        terminalCount.setAllCount(androiCountIntAnother + iosCountIntAnother + otherAnotherIntAnther);
        for (int i = index; i >= 0; --i) {
            UserAccount userAccountAll = listOfAll.get(i);
            String formatDate = new SimpleDateFormat("yyyy-MM-dd").format(userAccountAll.getCreateDate());
            assemblyData(userAccountAll, formatDate);
            /*
             * if (flag) { UserAccountUtil.initDataList(listOfAll, "terminal", "createDate"); flag = false; }
             */
            assemblySumData(listOfAll.get(i), terminalCount);
        }
    }

    /**
     * 装配数据
     * @param userAccountAll 返回对象
     * @param date 日期
     */
    private void assemblyData(UserAccount userAccountAll, String date) {
        String ios = null;
        String android = null;
        String other = null;
        String web = null;
        UserAccount iosUserAccount = (UserAccount) UserAccountUtil.getObjFromColName("ios", date);
        if (iosUserAccount != null)
            ios = iosUserAccount.getCount();

        UserAccount androidUserAccount = (UserAccount) UserAccountUtil.getObjFromColName("android", date);
        if (androidUserAccount != null)
            android = androidUserAccount.getCount();

        UserAccount otherUserAccount = (UserAccount) UserAccountUtil.getObjFromColName("other", date);
        if (otherUserAccount != null)
            other = otherUserAccount.getCount();

        UserAccount webUserAccount = (UserAccount) UserAccountUtil.getObjFromColName("web", date);
        if (webUserAccount != null)
            web = webUserAccount.getCount();

        userAccountAll.setAndroid(android);
        userAccountAll.setIos(ios);

        /* userAccountAll.setTerminal("isHave"); */

        int otherCount = getSafeValueAsInt(other);
        int webCount = getSafeValueAsInt(web);
        int allCount = otherCount + webCount;
        userAccountAll.setDayOfCount(String.valueOf(getSafeValueAsInt(android) + getSafeValueAsInt(ios) + allCount));

        userAccountAll.setOther(String.valueOf(allCount));
    }

    private void assemblySumData(UserAccount userAccount, TerminalCount terminal) {
        String ios = userAccount.getIos();
        String android = userAccount.getAndroid();
        String getDayOfCount = userAccount.getDayOfCount();

        long iosInt = getSafeValueAsInt(ios);
        long androidInt = getSafeValueAsInt(android);
        //
        long getAllCountInt = terminal.getAllCount();
        long iosCountInt = terminal.getIosCount();
        long androidCountInt = terminal.getAndroidCount();
        long getDayOfCountInt = getSafeValueAsInt(getDayOfCount);

        iosCountInt += iosInt;
        terminal.setIosCount(iosCountInt);
        androidCountInt += androidInt;
        terminal.setAndroidCount(androidCountInt);
        long allCount = 0;

        allCount = getAllCountInt + getDayOfCountInt;
        terminal.setAllCount(allCount);

        userAccount.setIosCount(String.valueOf(iosCountInt));
        userAccount.setAndroidCount(String.valueOf(androidCountInt));
        userAccount.setAllCount(String.valueOf(allCount));
    }

    private int getSafeValueAsInt(String terminal) {
        return terminal == null ? 0 : Integer.parseInt(terminal);
    }

    private boolean getSafeValueAsObj(Object terminal) {
        return terminal == null ? false : true;
    }

}